package com.listeningframework.boot.codegen.database;

import com.listeningframework.boot.codegen.context.ConnectionContext;
import com.listeningframework.boot.codegen.context.Context;
import com.listeningframework.boot.codegen.context.TableMetaData;
import com.listeningframework.boot.codegen.exception.CodeGenException;
import org.apache.commons.lang3.StringUtils;

import java.sql.*;
import java.util.List;

/**
 * CodeGen Entity MetaData Loader
 *
 * @author Listening
 * @version $Id: MetaLoader.java, v 0.1 2016年12月4日 下午5:39:03 Listening Exp $
 */
public abstract class MetaLoader {

    /**
     * 执行脚本查詢
     *
     * @param table 要读取的表名称
     * @return List<MetaData>
     */
    protected List<TableMetaData> execute(String table) throws CodeGenException {
        Connection conn = null;
        Statement stat = null;
        ResultSet rs = null;
        try {
            ConnectionContext connectionContext = Context.getContext().getConnectionContext();
            String url = connectionContext.getURL();
            String username = connectionContext.getUsername();
            String password = connectionContext.getPassword();
            Class.forName(getDriver(connectionContext.getPlatform()));
            conn = DriverManager.getConnection(url, username, password);
            stat = conn.createStatement();
            rs = stat.executeQuery(getMetaSQL(table));
            return getTableMetaData(rs);
        } catch (ClassNotFoundException e) {
            throw new CodeGenException("数据库驱动不存在", e);
        } catch (SQLException e) {
            throw new CodeGenException("JDBC异常", e);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (stat != null) {
                    stat.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e) {
                throw new CodeGenException("释放资源异常", e);
            }
        }
    }

    /**
     * 查询MetaData结构的SQL语句
     *
     * @param table 表名称
     * @return String
     */
    protected abstract String getMetaSQL(String table);

    /**
     * 回调处理表结果MetaData查询结果
     *
     * @param rs 结果集
     * @return List<MetaData>
     * @throws SQLException
     */
    protected abstract List<TableMetaData> getTableMetaData(ResultSet rs) throws SQLException;

    /**
     * 查询表MetaData结构List
     *
     * @param table 要获取MetData的表名称
     * @return List<MetaData>
     */
    public List<TableMetaData> getMetaData(String table) throws CodeGenException {
        return execute(table);
    }

    /**
     * Get Driver Class
     */
    private String getDriver(String platform) throws CodeGenException {
        if (StringUtils.equalsIgnoreCase(platform, "mysql")) {
            return com.mysql.jdbc.Driver.class.getName();
        } else {
            throw new CodeGenException("不支持的数据库平台");
        }
    }

}
